package com.pro.common.log.warn.service;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.pro.baoyi.api.logWarn.model.db.LogFileSizeRecord;
import com.pro.common.log.warn.dao.LogFileSizeRecordDao;
import com.pro.common.service.service.EnumAuthDict;
import com.pro.framework.mybatisplus.BaseService;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.io.File;
import java.io.IOException;
import java.math.BigDecimal;
import java.nio.file.Files;
import java.nio.file.attribute.BasicFileAttributes;
import java.nio.file.attribute.FileTime;
import java.time.Instant;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;

@Service
@Slf4j
@AllArgsConstructor
public class LogFileSizeRecordService extends BaseService<LogFileSizeRecordDao, LogFileSizeRecord> {
    @Autowired
    private LogFileSizeRecordDao logFileSizeRecordDao;
    private static String logDir;
    // 只允许访问这些文件，避免路径穿越
    private static final Set<String> LOG_FILES = Set.of(
            "admin.log",
            "goods-collect.log",
            "sync.log",
            "goods-launch-shein.log",
            "goods-launch-temu.log",
            "goods-launch-tiktok.log",
            "pay.log",
            "user.log",
            "goods-order.log",
            "shop.log",
            "site-content.log"
    );

    @Transactional(rollbackFor = Exception.class)
    public void saveRecord() {
        logDir = EnumAuthDict.LOG_DIR.getValueCacheOrDefault("");
        List<LogFileSizeRecord> records = new ArrayList<>();
        Map<String, LogFileSizeRecord> lateMap = getLateMap();
        LOG_FILES.forEach(filename -> {
            File logFile = new File(logDir, filename);
            if (logFile.exists()) {
                LogFileSizeRecord record = new LogFileSizeRecord();
                record.setModule(filename.replace(".log", ""));
                long fileSizeInBytes = logFile.length();
                double fileSizeInKB = fileSizeInBytes / 1024.0;
                LogFileSizeRecord logFileSizeRecord = lateMap.get(record.getModule());
                BigDecimal oldSize = (logFileSizeRecord == null || logFileSizeRecord.getFileSize() == null) ? BigDecimal.ZERO : logFileSizeRecord.getFileSize();
                record.setFileSize(new BigDecimal(Double.toString(fileSizeInKB)));
                record.setIncreaseSize(new BigDecimal(Double.toString(fileSizeInKB)).subtract(oldSize));
                BasicFileAttributes attrs = null;
                try {
                    attrs = Files.readAttributes(logFile.toPath(), BasicFileAttributes.class);
                } catch (IOException e) {
                    log.warn("文件创建时间读取失败");
                }
                FileTime creationTime = attrs.creationTime();
                Instant instant = creationTime.toInstant();
                LocalDateTime creationDateTime = instant.atZone(ZoneId.systemDefault()).toLocalDateTime();
                record.setFileCreateTime(creationDateTime);
                records.add(record);
            }

        });
        super.saveOrUpdateBatch(records);

    }

    public Map<String, LogFileSizeRecord> getLateMap() {
        List<LogFileSizeRecord> latestRecordsByModule = logFileSizeRecordDao.getLatestRecordsByModule();
        return latestRecordsByModule.stream().collect(
                Collectors.toMap(LogFileSizeRecord::getModule, logFileSizeRecord -> logFileSizeRecord)
        );

    }

    public Map<String, List<LogFileSizeRecord>> getThirdMap(List<String> moduleNames) {
        List<LogFileSizeRecord> list = this.lambdaQuery().in(LogFileSizeRecord::getModule, moduleNames).eq(LogFileSizeRecord::getUsedStatus, false).list();
        Map<String, List<LogFileSizeRecord>> map = list.stream().collect(
                Collectors.groupingBy(LogFileSizeRecord::getModule)
        );
        list.forEach(logFileSizeRecord -> logFileSizeRecord.setUsedStatus(true));
        super.saveOrUpdateBatch( list);
        return map;
    }
}

